import store from "@src/store";
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig } from "axios"
import {history} from '@src/App'

export default class RequestManager{

    //单例表示一个类只能创建一个实例对象
    //静态属性 用于存储单例对象
    private static _singleton:RequestManager | undefined

  // 用于保存 axios 实例对象的属性
  private readonly _axios_instance: AxiosInstance;

    //将构造函数设置为私有 防止开发者在类的外部通过 new 关键创建类的实例对象
    private constructor(){

        //初始化一个新的axios实例对象
        this._axios_instance = axios.create({
            baseURL:process.env.REACT_APP_BASE_URL,

        })  
        //注册请求拦截器，在请求头中添加用户登录凭据
        this._axios_instance.interceptors.request.use((config)=>{
            //获取状态对象
            const state = store.getState()
            //获取用户登录凭据
            const token =   state.userReducer.credentials.token
            //判断用户登录凭据是否存在
            if(token) config.headers = {Authorization:`Bearer ${token}`}
            //如果存在 将其添加到请求头中
            return config
        })


        //注册响应拦截器
        this._axios_instance.interceptors.response.use((response)=>response.data,
        (error:unknown)=>{
            if(error instanceof AxiosError){
                if(error.response?.status===401){
                    //跳转登录页面
                    history.push('/login')
                }
            }
            //继续抛出错误  
            return Promise.reject(error)
        }
        )

    }
    
    //静态方法 获取单例对象
    public static get instance(){
        //判断单例对象是否存在
        if(typeof RequestManager._singleton === 'undefined'){
            //不存在 创建单例对象
            RequestManager._singleton = new RequestManager()
        }
        //返回单例对象
        return RequestManager._singleton
    }

    //供外部用于发送请求的方法
    public request<T=any,D=any> (config:AxiosRequestConfig<D>):Promise<T>{
        return this._axios_instance.request(config)
    }

}